package net.xdclass.user.service.impl;

import lombok.extern.slf4j.Slf4j;
import net.xdclass.common.constant.Cons;
import net.xdclass.common.enums.BizCodeEnum;
import net.xdclass.common.enums.MailType;
import net.xdclass.user.model.MailDTO;
import net.xdclass.user.componet.MailService;
import net.xdclass.user.service.NotifyService;
import net.xdclass.common.utils.CheckUtil;
import net.xdclass.common.utils.CommonUtil;
import net.xdclass.common.JsonData;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class NotifyServiceImpl implements NotifyService {

    @Autowired
    private MailService mailService;
    @Autowired
    private RedisTemplate redisTemplate;

    private static final String SUBJECT = "小滴课堂验证码";
    private static final String CONTENT = "本次验证码是 %s, 有效时间5分钟！请勿外泄！";
    /** 验证码有效时间：10m */
    private static final long CODE_EXPIRE = 60 * 1000 *10;

    /**
     * 校验验证码
     *
     * @param to   接受者，用于构建cacheKey
     * @param type
     * @param code
     * @return
     */
    @Override
    public boolean verifyCode(String to, MailType type, String code) {
        String cacheKey = String.format(Cons.CODE_KEY, type.name(), to);
        String cacheValue = (String) redisTemplate.opsForValue().get(cacheKey);
        if (StringUtils.isNotEmpty(cacheValue)){
            String cacheCode = cacheValue.split("_")[0];
            if (code.equals(cacheCode)){
                redisTemplate.delete(cacheKey);
                return true;
            }
            long ttl = Long.parseLong(cacheValue.split("_")[1]);
            long differ = CommonUtil.getCurrnetTimeStamp() - ttl;
            if (differ >= CODE_EXPIRE){
                return false;
            }
        }
        return false;
    }

    @Override
    public JsonData sendCaptcha(String to, MailType type) {
        String cacheKey = String.format(Cons.CODE_KEY, type.name(), to);
        String cacheValue = (String) redisTemplate.opsForValue().get(cacheKey);
        if (StringUtils.isNotEmpty(cacheValue)){
            long ttl = Long.parseLong(cacheValue.split("_")[1]);
            long differ = CommonUtil.getCurrnetTimeStamp() - ttl;
            if (differ < 60 * 1000){
                // 60s 内重复发送验证码
                log.warn("验证码重复发送，时间间隔 {}.", differ / 1000);
                return JsonData.buildResult(BizCodeEnum.CODE_LIMITED);
            }
        }
        // 拼接验证码 code_timestamp
        String randomCode = CommonUtil.getRandomCode(6);
        log.info("邮件验证码 {}", randomCode);
        String code = randomCode + "_" + CommonUtil.getCurrnetTimeStamp();
        redisTemplate.opsForValue().set(cacheKey, code, CODE_EXPIRE, TimeUnit.MILLISECONDS);
        if(CheckUtil.isEmail(to)){
            MailDTO mail = new MailDTO.MailBuilder()
                    .to(to)
                    .date(new Date())
                    .subject(SUBJECT)
                    .text(String.format(CONTENT, randomCode))
                    .build();
            //邮箱验证码
            mailService.sendSimpleMail(mail);
            return JsonData.buildSuccess();

        }else if(CheckUtil.isPhone(to)){
            // TODO 短信验证码
        }

        return JsonData.buildResult(BizCodeEnum.CODE_TO_ERROR);
    }
}
